package com.moorror.codegenvel.view.window.codegenxrender.view;

import com.google.common.collect.Sets;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import com.moorror.codegenvel.common.select.MROneSelect;
import com.moorror.codegenvel.common.sql.SqlTableColumnDesc;
import com.moorror.codegenvel.tab.TabJsonWrap;
import com.moorror.codegenvel.tab.TabWrapEditor;
import com.moorror.codegenvel.common.table.TableAddNewRowAction;
import com.moorror.codegenvel.common.table.TreeLineWrap;
import com.moorror.codegenvel.common.tree.actions.TransferCallbackAction;
import com.moorror.codegenvel.constant.CodeGenByVelocityConstant;
import com.moorror.codegenvel.db.mysql.utils.HikaricpUtils;
import com.moorror.codegenvel.db.sqlite.entity.CodeGenXRenderConnect;
import com.moorror.codegenvel.db.sqlite.entity.CodeGenXRenderTableConfig;
import com.moorror.codegenvel.utils.*;
import com.moorror.codegenvel.view.panel.json.JsonPathEvaluateSnippetViewJava;
import com.moorror.codegenvel.view.window.codegen.domain.TableConstant;
import com.moorror.codegenvel.view.window.codegenxrender.domain.TableSchemaColumnDesc;
import com.moorror.codegenvel.view.window.codegenxrender.utils.TabLeftXRenderUtils;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.tuple.Pair;

import javax.swing.*;
import java.awt.*;
import java.util.List;
import java.util.Map;

/**
 * @Author jiyanghuang
 * @Date 2025/10/26 12:17
 */
public class TabGenCodeSchema extends JPanel {

    public static final String TYPE_SCHEMA_XRENDER_ARRAY = "XRender_array";

    public static final String TYPE_SCHEMA_XRENDER_OBJECT = "XRender_object";


    protected JPanel toolBarPanel;

    private Project project;

    private CodeGenXRenderTableConfig codeGenXRenderTableConfig;

    private Editor editor;

    private TabJsonWrap templateJsonValue;

    private JsonPathEvaluateSnippetViewJava jsonView;

    @Getter
    @Setter
    private String typeSchema = TYPE_SCHEMA_XRENDER_OBJECT;

    /**
     * 关于表格
     */
    private ToolbarDecorator decorator;

    private JBTable tableView;

    private JPanel tablePanel;

    public TabGenCodeSchema(Project project, CodeGenXRenderTableConfig codeGenXRenderTableConfig) {
        this.project = project;
        this.codeGenXRenderTableConfig = codeGenXRenderTableConfig;
        toolBarPanel = new JPanel();
        toolBarPanel.setLayout(new BorderLayout());
        setLayout(new BorderLayout());
        add(toolBarPanel, BorderLayout.NORTH);

        jsonView = new JsonPathEvaluateSnippetViewJava(project, null);
        editor = TabWrapEditor.createEditorStatic("", "sql");

        // 关于生成 table 逻辑
        tableView = TreeLineWrap.tableView(TableSchemaColumnDesc.class, Lists.newArrayList(), project);
        ListTableModel listTableModel = (ListTableModel) tableView.getModel();
        decorator = ToolbarDecorator.createDecorator(tableView);
        TableAddNewRowAction addLineAction = new TableAddNewRowAction(TableSchemaColumnDesc.class, listTableModel);
        decorator.setAddAction(addLineAction);
        tablePanel = decorator.createPanel();

        OnePixelSplitter splitter = new OnePixelSplitter(0.5f);
        splitter.setFirstComponent(tablePanel);
        splitter.setSecondComponent(jsonView);

        add(splitter, BorderLayout.CENTER);
        this.templateJsonValue = templateJsonValue;

        installActions();
    }

    protected void installActions() {

        DefaultActionGroup actionGroup = new DefaultActionGroup("SchemaGroup", false);
        if (null != ApplicationManager.getApplication()) {
//            sqlConfigAction = new SQLConfigAction(this.editor, this::updateTableInfo);
            actionGroup.add(new TransferCallbackAction("Fetch Table Column", "Fetch Table Column", AllIcons.Actions.Edit, this::fetchTableColumn));
            actionGroup.add(new MROneSelect(Sets.newHashSet(TYPE_SCHEMA_XRENDER_OBJECT, TYPE_SCHEMA_XRENDER_ARRAY), "Generate Type", (s) -> {
                typeSchema = s;
            }));
            if(CodeGenByVelocityConstant.PLUGIN_FOR_SELF){
                actionGroup.add(new TransferCallbackAction("Fetch Saved Schema", "Fetch Saved Schema", AllIcons.Actions.Find, this::fetchSaveSchema));
            }
            actionGroup.add(new TransferCallbackAction("Gen Form Schema", "Gen Form Schema", AllIcons.Actions.EditScheme, this::genFormSchema));
            if(CodeGenByVelocityConstant.PLUGIN_FOR_SELF){
                actionGroup.add(new TransferCallbackAction("Merge Saved Schema", "Merge Saved Schema", AllIcons.Vcs.Merge, this::mergeSchema));
                actionGroup.add(new TransferCallbackAction("Save Schema", "Save Schema", AllIcons.Actions.MenuSaveall, this::schemaSave));
            }
//            actionGroup.add(new SQLEditConfigAction(this::fetchTableInfo, this::updateTableInfo, "Edit Exist SQL TableInfo"));

//            actionGroup.addSeparator();
//            actionGroup.add(new AddConfigAction());
//            actionGroup.addSeparator();
//            actionGroup.add(new DuplicateAction());
//            actionGroup.add(new SearchAction(tree));
        }

        GuiUtils.installActionGroupInToolBar(actionGroup, toolBarPanel, ActionManager.getInstance(), ActionPlaces.TOOLBAR, true);
    }

    public void fetchTableColumn(AnActionEvent e) {
        String url = "jdbc:mysql://localhost:3306/trade_single_sys?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true"; // 注意这里不指定具体数据库名，因为我们将在运行时获取数据库列表。
        String user = "root";
        String password = "root123456";
        String tableName = "trade_single_order";
        List<SqlTableColumnDesc> tableColumns = HikaricpUtils.tableColumns(url, user, password, tableName);
        List<TableSchemaColumnDesc> schemaColumnDescs = MConverterUtils.aToBList(tableColumns, TabGenCodeSchema::convert);
        Pair<ColumnInfo[], List<TreeLineWrap>> header = TreeLineWrap.header(TableSchemaColumnDesc.class, schemaColumnDescs, project);
        ListTableModel listTableModel = (ListTableModel) tableView.getModel();
        listTableModel.setItems(header.getRight());
    }

    /**
     * 获取已经保存的 schema
     * @param e
     */
    public void fetchSaveSchema(AnActionEvent e) {
        CodeGenXRenderConnect connect = TabLeftXRenderUtils.model(e.getProject());
        String sql = "SELECT id,schema_json FROM trade_single_codegen_model_schema_config WHERE name_model = ? AND scene = ?";
        Map<String, String> re = HikaricpUtils.queryColumnInvoke(connect.getUrl(), connect.getUsername(), connect.getPassword(), "", "id", "schema_json");
    }

    /**
     * 遍历表格的内容及已经存在的Schema进行合并
     * @param e
     */
    public void mergeSchema(AnActionEvent e) {

    }

    /**
     * 遍历表格的内容及已经存在的Schema进行合并
     * @param e
     */
    public void schemaSave(AnActionEvent e) {
        TabLeftUtils.rootModel(e.getProject());
    }

    public void genFormSchema(AnActionEvent e) {
        List<TableSchemaColumnDesc> columnList = columnList();
        if(null == typeSchema){
            typeSchema = TYPE_SCHEMA_XRENDER_OBJECT;
        }
        String jsonSchema = "";
        if (TYPE_SCHEMA_XRENDER_OBJECT.equals(typeSchema)) {
            jsonSchema = XRenderSchemaGenUtils.object(columnList);
        } else if (TYPE_SCHEMA_XRENDER_ARRAY.equals(typeSchema)) {
            jsonSchema = XRenderSchemaGenUtils.array(columnList);
        }
        jsonView.setSource(jsonSchema);
        System.out.println("this --->");
    }

    public List<TableSchemaColumnDesc> columnList(){
        ListTableModel listTableModel = (ListTableModel) tableView.getModel();
        List<TableSchemaColumnDesc> columnList = Lists.newArrayList();
        List items = listTableModel.getItems();
        for(Object item : items){
            TreeLineWrap treeLineWrap = (TreeLineWrap)item;
            columnList.add((TableSchemaColumnDesc)treeLineWrap.getT());
        }
        return columnList;
    }

    public void fillColumnList(List<TableSchemaColumnDesc> schemaColumnDescs){
        Pair<ColumnInfo[], List<TreeLineWrap>> header = TreeLineWrap.header(TableSchemaColumnDesc.class, schemaColumnDescs, project);
        ListTableModel listTableModel = (ListTableModel) tableView.getModel();
        listTableModel.setItems(header.getRight());
    }

    public static TableSchemaColumnDesc convert(SqlTableColumnDesc columnDesc){
        TableSchemaColumnDesc tableSchemaColumnDesc = new TableSchemaColumnDesc();
        tableSchemaColumnDesc.setColumnName(columnDesc.getColumnName());
        tableSchemaColumnDesc.setName(NameUtils.underScoreLowerCamel(columnDesc.getColumnName()));
        tableSchemaColumnDesc.setTypeJava(TableConstant.fetchType(columnDesc.getTypeName()));
        tableSchemaColumnDesc.setComment(columnDesc.getComment());
        tableSchemaColumnDesc.setTitle(columnDesc.getComment());
        tableSchemaColumnDesc.setWidget("");
        return tableSchemaColumnDesc;
    }

    public void fillSchemaJson(String json){
        jsonView.setSource(json);
    }

    public String fetchSchemaJson(){
        return jsonView.text();
    }

}
